package com.powernode.controller;

import com.powernode.config.MinioConfig;
import com.powernode.entity.UserInfo;
import com.powernode.result.R;
import com.powernode.service.UserContractService;
import com.powernode.service.UserImageService;
import com.powernode.service.UserInfoService;
import io.minio.*;
import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.net.URLEncoder;
import java.util.List;

@CrossOrigin // 支持跨域访问
@RestController
public class UserController {
    @Resource
    private UserInfoService userInfoService;
    @Resource
    private UserImageService userImageService;
    @Resource
    private UserContractService userContractService;
    @Resource
    private MinioClient minioClient;
    @Resource
    private MinioConfig minioConfig;

    @GetMapping("/api/users")
    public R users(){
        List<UserInfo> userInfoList = userInfoService.list();
        return R.OK(userInfoList);
    }

    @PostMapping("/api/user/image")
    public R image(MultipartFile file, @RequestParam("id") Integer id) throws Exception { // 接收前端传递过来的文件

        System.out.println("前端传递过来的image文件：" + file.getOriginalFilename()); // 1234.jpg
        String subfix = file.getOriginalFilename().substring(file.getOriginalFilename().indexOf("."));
        String object = id + subfix;

        // bucketExists() 用于检查指定的存储桶是否存在，返回布尔值，表示存储桶是否存在；
        boolean isBucketExists = minioClient.bucketExists(
                // BucketExistsArgs.builder().bucket("my-file").build()
                BucketExistsArgs.builder().bucket(minioConfig.getBucket()).build()
        );
        if (!isBucketExists) {
            // minioClient.makeBucket(MakeBucketArgs.builder().bucket("my-file").build());
            minioClient.makeBucket(MakeBucketArgs.builder().bucket(minioConfig.getBucket()).build());
        }

        ObjectWriteResponse objectWriteResponse = minioClient.putObject(PutObjectArgs.builder()
                // .bucket("my-file")
                .bucket(minioConfig.getBucket())
                .object(object)
                .stream(file.getInputStream(), file.getSize(), -1) // 最后一个参数是缓冲区大小，给-1让其自己决定
                .build());
        System.out.println(objectWriteResponse);
        System.out.println(objectWriteResponse.etag());

        // 修改数据库
         userImageService.saveOrUpdateUserImage(id, minioConfig.getBucket(), object);

        return R.OK("文件上传成功");
    }

    @PostMapping("/api/user/contract")
    public R contract(MultipartFile file, @RequestParam("id") Integer id) throws Exception { // 接收前端传递过来的文件

        System.out.println("前端传递过来的contract文件：" + file.getOriginalFilename());
        String subfix = file.getOriginalFilename().substring(file.getOriginalFilename().indexOf("."));
        String object = id + subfix;

        // bucketExists() 用于检查指定的存储桶是否存在，返回布尔值，表示存储桶是否存在；
        boolean isBucketExists = minioClient.bucketExists(
                // BucketExistsArgs.builder().bucket("my-file").build()
                BucketExistsArgs.builder().bucket(minioConfig.getBucket()).build()
        );
        if (!isBucketExists) {
            // minioClient.makeBucket(MakeBucketArgs.builder().bucket("my-file").build());
            minioClient.makeBucket(MakeBucketArgs.builder().bucket(minioConfig.getBucket()).build());
        }

        ObjectWriteResponse objectWriteResponse = minioClient.putObject(PutObjectArgs.builder()
                // .bucket("my-file")
                .bucket(minioConfig.getBucket())
                .object(object)
                .stream(file.getInputStream(), file.getSize(), -1) // 最后一个参数是缓冲区大小，给-1让其自己决定
                .build());
        System.out.println(objectWriteResponse);

        // 修改数据库
        userContractService.saveOrUpdateUserContract(id, minioConfig.getBucket(), object);

        return R.OK();
    }

    @GetMapping("/api/user/{id}")
    public R user(@PathVariable(value = "id") Integer id){
        UserInfo userInfo = userInfoService.getUserById(id);
        return R.OK(userInfo);
    }

    @PutMapping("/api/user")
    public R updateUser(UserInfo userInfo){
        boolean update = userInfoService.updateById(userInfo);
        return update ? R.OK() : R.FAIL();
    }

    @GetMapping("/api/download/{id}")
    public void download(@PathVariable("id") Integer id, HttpServletResponse response) throws Exception {
        UserInfo userInfo = userInfoService.getUserById(id);

        String bucket = userInfo.getUserContractDO().getBucket();
        String object = userInfo.getUserContractDO().getObject();

        // 想让浏览器弹出下载框，后端需设置响应头信息
        response.setContentType("application/octet-stream");
        response.setCharacterEncoding("UTF-8");
        response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(object, "UTF-8"));

        GetObjectResponse getObjectResponse = minioClient.getObject(GetObjectArgs.builder()
                .bucket(bucket)
                .object(object)
                .build());

        getObjectResponse.transferTo(response.getOutputStream());
    }
}
